package com.teziyou.commodity.core.thrift;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * 类名名称: ConnectionProviderImpl/连接提供接口实现 <br/>
 *
 * @author zhoucl 2014年7月30日
 * @version 
 * @since JDK 1.7
 */
@SuppressWarnings("unchecked")
public class ConnectionProviderImpl implements ConnectionProvider, InitializingBean, DisposableBean {
	private String url;
	
	private int timeout;
	
	private int type;
	
	private List<ObjectPool<?>> objectPools = null;
	
	@Override
	public TTransportBean getConnection() {
		ObjectPool<TSocket> objectPool = null;
		int maxNumIdle = 0;
		int index = 0;
		
		for(int i = 0; i < objectPools.size(); i++) {
			if(objectPools.get(i).getNumIdle() > maxNumIdle) {
				maxNumIdle = objectPools.get(i).getNumIdle();
				index = i;
			}
		}
		
		objectPool = (ObjectPool<TSocket>)objectPools.get(index);
		
		TTransportBean tTransportBean = new TTransportBean();
		TTransport tTransport = null;
		try {
			//System.err.println("拿一个");
			tTransport = objectPool.borrowObject();
			//System.err.println(tTransport.getClass());
			tTransportBean.settTransport(tTransport);
			tTransportBean.setPoolIndex(index);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		
		return tTransportBean;
	}

	@Override
	public void close(TTransportBean tTransportBean) {
		try {
			ObjectPool<TTransport> objectPool = (ObjectPool<TTransport>) objectPools.get(tTransportBean.getPoolIndex());
			objectPool.returnObject(tTransportBean.gettTransport());
		} catch (Exception e) {
			throw new RuntimeException("error returnCon()", e);
		}
	}
	
	@Override
	public void destroy() throws Exception {
		try {
			for(ObjectPool<?> objectPool : objectPools) {
				objectPool.close();
			}
		} catch (Exception e) {
			throw new RuntimeException("erorr destroy()", e);
		}
		
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		GenericObjectPoolConfig config = new GenericObjectPoolConfig();
		
		objectPools = new ArrayList<>();
		
		String[] urlArray = url.split(";");
		for(String  url: urlArray) {
			String[] urlArr = url.split(":");
			String ip = urlArr[0];
			Integer port = Integer.parseInt(urlArr[1]);
			objectPools.add(new GenericObjectPool<>(new ThriftPoolableObjectFactory(ip, port, timeout, type), config));
			//System.out.println(url + " added to objectPools");
		}
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	public String getUrl() {
		return url;
	}

	public int getTimeout() {
		return timeout;
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

}
